package com.gscitysfy.cus.drain.modules.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gscitysfy.cloudfrmwk.assistant.domain.Result;
import com.gscitysfy.cloudfrmwk.assistant.enums.ResultStatus;
import com.gscitysfy.cloudfrmwk.portal.feign.GeTuiService;
import com.gscitysfy.cloudfrmwk.portal.feign.UserService;
import com.gscitysfy.cloudfrmwk.portal.vo.UserInfoVO;
import com.gscitysfy.cus.drain.config.BusinessException;
import com.gscitysfy.cus.drain.modules.common.entity.MoperMnSmsLog;
import com.gscitysfy.cus.drain.modules.common.enums.NoticeType;
import com.gscitysfy.cus.drain.modules.common.service.IMoperMnSmsLogService;
import com.gscitysfy.cus.drain.modules.common.service.SendNoticeService;
import com.gscitysfy.cus.drain.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 史鹏 E-mail:754572960@qq.com
 * @version 创建时间：2022/4/27 14:55
 */
@Slf4j
@Service
public class SendNoticeServiceImpl implements SendNoticeService {
    @Autowired
    private UserService userService;
    @Autowired
    private GeTuiService geTuiService;

    @Resource
    private IMoperMnSmsLogService logService;

    @Value("${appSecret}")
    private String app_secret;
    @Value("${smsUrl}")
    private String sms_url;

    /**
     * 发送短信内容限制
     */
    private static final int SMS_LENGTH = 450;

    @Override
    public void sendNotice(List<String> userIdList, String content, NoticeType noticeType) {
        Assert.notEmpty(userIdList, "userIdList不可为空");
        if (StringUtils.isNotBlank(content) && content.length() > SMS_LENGTH) {
            content = content.substring(0, SMS_LENGTH - 1);
        }
        switch (noticeType) {
            case SMS:
                sendSMS(userIdList, content, noticeType);
                break;
            case GETUI:
                sendGetui(userIdList, content , noticeType);
                break;
            case ALL:
                sendGetui(userIdList, content , noticeType);
                sendSMS(userIdList, content, noticeType);
                break;
            default:
                throw new BusinessException("无效的消息通知方式");
        }
    }

    private void sendGetui(List<String> userIdList, String content, NoticeType noticeType) {
        //消息json字符串（格式：{title:"标题",content:"内容",payload:"自定义数据"}）
        JSONObject message = new JSONObject();
        message.put("title", "综合运维通知");
        message.put("content", content);
        message.put("payload", "");

        for (String userId : userIdList) {
            try {
                Result result = geTuiService.pushSingleMessage(userId, message.toJSONString());
                if (ResultStatus.OK.getCode() != result.getCode()) {
                    //发送失败 不抛出 正常执行操作
                    log.error("调用个推发送短信异常", result.getMessage());
                }
            } catch (Exception exception) {
                log.warn("调用个推发送短信异常", exception);
                throw new BusinessException(exception);
            }
        }
    }

    private void sendSMS(List<String> userIdList, String content, NoticeType noticeType) {
        for (String userId : userIdList) {
            if (StringUtils.isNotBlank(content)) {
                Result<UserInfoVO> userInfoVOResult = userService.getUserInfoById(userId);
                if (ResultStatus.OK.getCode() == userInfoVOResult.getCode()) {
                    if (userInfoVOResult.getData() == null){
                        continue;
                    }
                    UserInfoVO userInfoVO = userInfoVOResult.getData();
                    try {
                        JSONObject resultObject = sendSms(userInfoVO.getPhoneNumber(), content);
                        int sendStat;
                        if (resultObject != null && 200 == resultObject.getIntValue("status")) {
                            String smsNo = resultObject.getString("data");
                            log.info("发送成功,短信发送流水：" + smsNo);
                            sendStat = 1;
                        } else {
                            sendStat = 0;
                            log.warn("短信发送失败！");
                        }
                        MoperMnSmsLog log = new MoperMnSmsLog();
                        log.setNoticeType(noticeType.name());
                        log.setContent(content);
                        log.setUserId(userId);
                        log.setMobile(userInfoVO.getPhoneNumber());
                        log.setSendState(sendStat);
                        log.setSendResult(resultObject.toJSONString());
                        logService.save(log);
                    } catch (Exception e) {
                        log.warn("调用短信发送网关异常", e);
//                        throw new BusinessException(e);
                    }
                } else {
                    throw new BusinessException("获取用户信息失败：" + userInfoVOResult.getMessage());
                }
            } else {
                throw new BusinessException("短信发送内容为空");
            }
        }
    }

    private JSONObject sendSms(String mobile, String content) {
        Map<String, Object> headers = new HashMap<>();
        headers.put("app_secret", app_secret);
        headers.put("Content-Type", "application/json");
        JSONObject params = new JSONObject();
        params.put("businessType", "sms");
        params.put("content", content);
        params.put("mobile", Collections.singletonList(mobile));

        String resultStr = null;
        try {
            log.info("推送消息，headers:{},params:{}", JSON.toJSONString(headers), JSON.toJSONString(params));
            resultStr = HttpClientUtil.httpPostRequest(sms_url + "/api/gemp/dispatch/sms/send_with_callback",
                    headers, params.toJSONString());
            log.info("推送消息，response:{}", resultStr);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        return JSON.parseObject(resultStr);
    }

}
